/*
 * MapParser.cpp
 *
 *  Created on: 17.11.2013
 *      Author: dima
 */

#include "MapParser.hpp"

#include "../Globals.hpp"

#include <fstream>
#include <sstream>


Tanks::
Resources::
MapParser::
MapParser(int argMaxX,
          int argMaxY,
          std::string argMyDir,
          std::string argFilename) :
  m_mapFilename(argFilename),
  m_myDir(argMyDir),
  m_maxX(argMaxX),
  m_maxY(argMaxY)
{}


Tanks::
Resources::
MapParser::
~MapParser()
{
  for(unsigned int i = 0; i < m_mapObjects.size(); ++i)
  {
    delete m_mapObjects[i];
  }
}



bool
Tanks::
Resources::
MapParser::
Parse()
{
  std::ifstream file;
  std::string filePath = m_myDir + "Maps" + Globals::directorySplitter + m_mapFilename.c_str();
  file.open(filePath.c_str(), std::ios_base::in);
  if(!file)
  {
    throw std::string("File missing: " + filePath);
    return false;
  }

  std::string line;
  while(std::getline(file, line))
  {
    if(line.empty() ||
       line.at(0) == '#')
    {  // ignore comments and empty lines
      continue;
    }
    std::stringstream lineStream(line);
    lineStream.clear();
    std::string value;
    std::vector<std::string> values;
    while(std::getline(lineStream, value, ';'))
    {
      values.push_back(value);
    }
    if(values.size() != 6)
    {  // skip lines with wrong format
      continue;
    }
    int x, y, w, h;
    Tanks::Model::GameObjectType type;
    int typeTemp;
    std::string img;
    char * end;
    x = strtol(values[0].c_str(), &end, 10);
    if(*end != '\0') { continue; }

    y = strtol(values[1].c_str(), &end, 10);
    if(*end != '\0') { continue; }

    w = strtol(values[2].c_str(), &end, 10);
    if(*end != '\0') { continue; }

    h = strtol(values[3].c_str(), &end, 10);
    if(*end != '\0') { continue; }

    typeTemp = strtol(values[4].c_str(), &end, 10);
    if(*end != '\0') { continue; }

    img = values[5];

    if(!CheckValidity(x, y, w, h, typeTemp, img)) continue;
    type = (Tanks::Model::GameObjectType)typeTemp;

    AddMapObject(x, y, w, h, type, img);
  }

  return true;
}


bool
Tanks::
Resources::
MapParser::
CheckValidity(int argX,
              int argY,
              int argW,
              int argH,
              int argType,
              std::string argImgFilename)
{
  return (argX    >= 0 && argX <= m_maxX) &&
         (argY    >= 0 && argY <= m_maxY) &&
         argW >= 0 &&
         argH >= 0 &&
         (argType >= Tanks::Model::SolidBlock && argType <= Tanks::Model::Land);
}


void
Tanks::
Resources::
MapParser::
AddMapObject(int argX,
             int argY,
             int argW,
             int argH,
             Tanks::Model::GameObjectType argType,
             std::string argImgFilename)
{
  MapObject * object = new MapObject;
  SDL_Rect rect;
  rect.x = argX;
  rect.y = argY;
  rect.w = argW;
  rect.h = argH;
  object->m_rect = rect;
  object->m_type = argType;
  object->m_imageFilename = argImgFilename;
  m_mapObjects.push_back(object);
}



